/*************************************************************************
    Projet  -  Sport Collectif pour Robots
                             -------------------
    Auteur  -  Kevin Vandel
*************************************************************************/

//--- Interface de la classe <Communication> (fichier Communication.h) ---
#ifndef COMMUNICATION_H_
#define COMMUNICATION_H_

//--------------------------------------------------- Interfaces utilisees
#include <string>
#include <termios.h>

using namespace std;

//------------------------------------------------------------- Constantes
#define RECEPTION_TIMEOUT 250 //Temps max (en ms) d'attente de reponse d'un khepera


//------------------------------------------------------------------------
// Role de la classe <Communication>
//	Gere l'interface de communication avec les robots Khepera.
//------------------------------------------------------------------------


class Communication
{
//----------------------------------------------------------------- PUBLIC
public:
//--------------------------------------------------------------- Enumeres
	enum BaudRate
	{
		CCOM_BR57600,
		CCOM_BR19200,
		CCOM_BR9600,
		CCOM_BR4800,
		CCOM_BR2400,
		CCOM_BR1200,
		CCOM_BR600
	};
	enum Erreur
	{
		ER_CCOM = -1000,
		ER_PORT_COM_NOT_OPENED 			= Communication::ER_CCOM-1,
		ER_PORT_COM_ALREADY_OPENED		= Communication::ER_CCOM-2,
		ER_BAUD_RATE_UNDEFINED 			= Communication::ER_CCOM-3,
		ER_CAR_SIZE_UNDEFINED  			= Communication::ER_CCOM-4,
		ER_PARITY_MODE_UNDEFINED  		= Communication::ER_CCOM-5,
		ER_COUNT_STOP_BIT_UNDEFINED 	= Communication::ER_CCOM-6,
		ER_CONFIGURATION_UNAPPLICABLE 	= Communication::ER_CCOM-7
	};
	enum Parity
	{
		CCOM_NONE,
		CCOM_EVEN, /* pair */
		CCOM_ODD
	};
	enum DataBits
	{
		CCOM_8_BITS,
		CCOM_7_BITS,
		CCOM_6_BITS,
		CCOM_5_BITS
	};
	enum StopBits
	{
		CCOM_1_BIT,
		CCOM_2_BIT
	};


//----------------------------------------------------- Methodes publiques
	void Fermer();
	// Mode d'emploi :
	//	Fermeture du port de communication ouvert.

	bool Ouvrir(string port);
	// Mode d'emploi :
	//	Ouverture du port de communication "port".
	//	Renvoie true si succes, false sinon.

	bool ConfigurerPort(BaudRate baudRate, DataBits countBits, Parity parity, StopBits countBitsStop);
	// Mode d'emploi :
	//	Configuration du port de communication ouvert.

	string const& getOpenedPort() const;
	// Getter


	/************************** COMMANDES KHEPERA ***************************/

	bool ConfigurerPidVitesse(int Kp, int Ki, int Kd);
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Configure the speed PID controller" (Cf. doc Khepera),
	//	les parametres represantant les coefficients a affecter au regulateur PID de la vitesse.
	//	Renvoie true si le robot accuse reception, false sinon.

	pair<string, string> GetVersionLogiciel();
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Read software version" (Cf. doc Khepera).
	//	Renvoie la version du BIOS (first) et la version du protocole (second).

	bool SetPositionRoues(int roueGauche, int roueDroite);
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Set a position to be reached" (Cf. doc Khepera),
	//	les parametres represantant les positions a atteindre pour les deux roues.
	//	Renvoie true si le robot accuse reception, false sinon.

	bool SetVitesseRoues(int roueGauche, int roueDroite);
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Set speed" (Cf. doc Khepera),
	//	les parametres represantant les vitesses a appliquer aux deux roues.
	//	Renvoie true si le robot accuse reception, false sinon.

	pair<int, int> GetVitesseRoues();
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Read speed" (Cf. doc Khepera).
	//	Renvoie les vitesses gauche (first) et droite (second).

	bool ConfigurerPidPosition(int Kp, int Ki, int Kd);
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Configure the position PID controller" (Cf. doc Khepera),
	//	les parametres represantant les coefficients a affecter au regulateur PID de la position.
	//	Renvoie true si le robot accuse reception, false sinon.

	bool SetCompteurPositionRoues(int roueGauche, int roueDroite);
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Set position to the position counter" (Cf. doc Khepera),
	//	les parametres represantant les valeurs des compteurs des deux moteurs.
	//	Renvoie true si le robot accuse reception, false sinon.

	pair<int, int> GetPositionRoues();
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Read position" (Cf. doc Khepera).
	//	Renvoie les positions gauche et droite.

	bool ConfigurerControleurPosition(int vitMaxG, int accG, int vitMaxD, int accD);
	// Mode d'emploi :
	//	Envoi au robot Khepera de la commande "Configure the speed profile controller" (Cf. doc Khepera),
	//	les parametres represantant les vitesses maximales et accelerations des roues gauche et droite.
	//	Renvoie true si le robot accuse reception, false sinon.


//-------------------------------------------- Constructeurs - destructeur
	Communication();
	virtual ~Communication();



//------------------------------------------------------------------ PRIVE
private:
//------------------------------------------------------- Methodes privees
	bool recevoirDonnees(string & data);
	// Mode d'emploi :
	//	Lit sur le port de communication ouvert jusqu'a la reception des
	//	caracteres de fin de trame ("\r\c"), ou jusqu'a expiration du
	//	timer.
	//	Renvoie false si le timer a expire (perte de communication) et
	//	true sinon.

	int envoyerDonnees(string & data);
	// Mode d'emploi :
	//	Envoie le message <data> sur le port de communication ouvert
	//	Renvoie le nombre de caracteres ecrits.
	//
	// Contrat :
	//  <data> ne doit pas contenir le doublet de fin de message.


//------------------------------------------------------- Attributs prives
	string port;			//Port de communication utilise
	int fileDescriptor;		//Descripteur de fichier pointant sur le buffer d'E/S
	termios configuration;	//Configuration du port de communication
};

#endif /* COMMUNICATION_H_ */
